/**
 * 通用markdown文章渲染页
 * 左侧aside为markdown文件navbar
 * 右侧content为markdown内容
 */

export type Title = {
  key: string
  href: string
  title: string
  children?: Title[]
  nodeName: any
}

/**
 * 格式化markdown标题的dom节点数组
 */
export const formatNavItem = (headerDom: NodeListOf<HTMLElement>) => {
  // 将NodeList转换为数组，并提取出需要的属性
  let headerArr = Array.prototype.slice.call(headerDom).map((item, index) => {
    const url = item?.getAttribute('id')
    let title = {
      href: '#' + url,
      key: '' + url,
      title: headerDom[index].innerText,
      children: [],
      nodeName: item.nodeName
    }
    return title
  }) as Title[]

  /**
   * (双重循环，从后往前，逐渐将子节点存入父节点children属性)
   * 1. 从后往前，将子标题直接存入前一个父级标题的children[]中
   * 2. 如果前一个标题与当前标题(或标题数组)无直系关系，则直接将当前标题(或标题数组解构后)放入list数组
   * 3. 循环多次，直到result数组长度无变化，结束循环
   */
  let result = headerArr
  let preLength = 0
  let newLength = result.length
  let num = 0
  while (preLength !== newLength) {
    num++
    preLength = result.length // 获取处理前result数组长度
    let list: Title[] = [] // list数组用于存储本次for循环结果
    let childList: Title[] = [] // childList存储遍历到的兄弟标题，用于找到父标题时赋值给父标题的children属性
    for (let index = result.length - 1; index >= 0; index--) {
      if (
        // 当前节点与上一个节点是兄弟节点，将该节点存入childList数组
        result[index - 1] &&
        result[index - 1].nodeName.charAt(1) ===
          result[index].nodeName.charAt(1)
      ) {
        childList.unshift(result[index])
      } else if (
        // 当前节点是上一个节点的子节点，则将该节点存入childList数组，将childList数组赋值给上一节点的children属性，childList数组清空
        result[index - 1] &&
        result[index - 1].nodeName.charAt(1) < result[index].nodeName.charAt(1)
      ) {
        childList.unshift(result[index])
        result[index - 1].children = [
          ...(result[index - 1].children as []),
          ...childList
        ]
        childList = []
      } else {
        // 当前节点与上一个节点无直系关系，或当前节点下标为0的情况
        childList.unshift(result[index])
        if (childList.length > 0) {
          list.unshift(...childList)
        } else {
          list.unshift(result[index])
        }
        childList = []
      }
    }
    result = list
    newLength = result.length // 获取处理后result数组长度
  }
  return result
}
